home *** CD-ROM | disk | FTP | other *** search
/ Aminet 40 / Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso / Aminet / mus / misc / DelfScope.lha / DelfScope / src / DelfScope.c < prev    next >
C/C++ Source or Header  |  2000-10-03  |  21KB  |  685 lines

  1. /*****************************************************************************
  2.  
  3.     DelfScope - oscilloscope/analyzer for Delfina DSP
  4.     Copyright (C) 2000  Michael Henke
  5.  
  6.     This program is free software; you can redistribute it and/or modify
  7.     it under the terms of the GNU General Public License as published by
  8.     the Free Software Foundation; either version 2 of the License, or
  9.     (at your option) any later version.
  10.  
  11.     This program is distributed in the hope that it will be useful,
  12.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.     GNU General Public License for more details.
  15.  
  16.     You should have received a copy of the GNU General Public License
  17.     along with this program; if not, write to the Free Software
  18.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  19.  
  20. *****************************************************************************/
  21.  
  22.  
  23. #define RTGMODE__not
  24.  
  25. #include <proto/exec.h>
  26. #include <proto/dos.h>
  27. #include <proto/timer.h>
  28. #include <proto/intuition.h>
  29. #include <proto/graphics.h>
  30. #include <proto/utility.h>
  31. #include <proto/reqtools.h>
  32. #include <exec/interrupts.h>
  33. #include <hardware/intbits.h>
  34. #include <exec/nodes.h>
  35. #include <exec/memory.h>
  36. #include <exec/libraries.h>
  37. #include <exec/execbase.h>
  38. #include <graphics/gfx.h>
  39. #include <graphics/rastport.h>
  40. #include <graphics/text.h>
  41. #include <graphics/displayinfo.h>
  42. #include <intuition/intuition.h>
  43. #include <intuition/screens.h>
  44. #include <devices/timer.h>
  45. #include <libraries/delfina.h>
  46. #include <libraries/reqtools.h>
  47. #include <math.h>
  48. #include <limits.h>
  49. #include <stdio.h>
  50. #include <stdlib.h>
  51. #include <string.h>
  52.  
  53. #include "scope_asm.h"
  54. #include "scope_dsp.h"
  55. extern struct DelfObj DSP56K_SCOPE;
  56.  
  57. static UBYTE version[]="$VER: DelfScope 0.1 (Tue 03-Oct-2000)";
  58. #ifdef RTGMODE
  59. static UBYTE template[]="-M=MODEID/K,-I=INPUT/K,RTG/S";
  60. #else
  61. static UBYTE template[]="-M=MODEID/K,-I=INPUT/K";
  62. #endif
  63.  
  64. static struct MsgPort *delfport=NULL;
  65. static struct DelfPrg *prg_scope=NULL;
  66. static struct DelfModule *mod_scope=NULL;
  67. struct Library *DelfinaBase=NULL;
  68. struct ReqToolsBase *ReqToolsBase=NULL;
  69. extern struct ExecBase *SysBase;    /*auto-init fills this!*/
  70. void *GFXBASE;  /*used by the ASM plot routines in RTG-mode*/
  71.  
  72. int vblank_count(void);
  73. int vblank_plot(void);
  74. int softint_plot(void);
  75. int check_idcmp(void);
  76. static struct Interrupt vblank_int=
  77. {
  78.     NULL,NULL, NT_INTERRUPT, 127, "DelfScope_VBLANK",   /* struct Node */
  79.     NULL,NULL
  80. };
  81. static struct Interrupt vblank_softint=
  82. {
  83.     NULL,NULL, NT_UNKNOWN, 32, NULL,    /* struct Node */
  84.     NULL,(void(*)(void))softint_plot
  85. };
  86. static struct Interrupt window_int=
  87. {
  88.     NULL,NULL, NT_UNKNOWN, 0, NULL,     /* struct Node */
  89.     NULL,(void(*)(void))check_idcmp
  90. };
  91.  
  92. static UBYTE *chipmem=NULL;
  93. static struct BitMap bmap=
  94. {
  95.     640/8, 480,         /* BytesPerRow, Rows */
  96.     0, 2, 0,            /* Flags, Depth, pad */
  97.     0,0,0,0,0,0,0,0     /* Planes */
  98. };
  99. static struct TextFont *textfont;
  100. static struct TextAttr textattr=
  101. {
  102.     "topaz.font", 8, FS_NORMAL, FPF_ROMFONT
  103. };
  104. static struct Screen *myscreen=NULL;
  105. static struct RastPort *rp;
  106. static struct NewScreen newscr=
  107. {
  108.     0, 0, 640, 480, 2,  /* LeftEdge, TopEdge, Width, Height, Depth */
  109.     0, 0, 0,            /* DetailPen, BlockPen, ViewModes */
  110.     AUTOSCROLL|SCREENQUIET|SCREENHIRES|CUSTOMBITMAP|CUSTOMSCREEN,   /* Type */
  111.     0, 0, 0, &bmap      /* Font, DefaultTitle, Gadgets, CustomBitMap */
  112. };
  113. static struct Window *mywindow=NULL;
  114. static struct NewWindow newwin=
  115. {
  116.     0, 0, 640, 480,     /* LeftEdge, TopEdge, Width, Height */
  117.     0, 0,               /* DetailPen, BlockPen */
  118.     IDCMP_VANILLAKEY|IDCMP_INACTIVEWINDOW|IDCMP_ACTIVEWINDOW, /* IDCMPFlags */
  119.     WFLG_RMBTRAP|WFLG_NOCAREREFRESH|WFLG_ACTIVATE|WFLG_BORDERLESS|WFLG_BACKDROP,    /* Flags */
  120.     0, 0, 0,            /* FirstGadget, CheckMark, Title */
  121.     0, 0,               /* Screen, BitMap */
  122.     0, 0, 0, 0,         /* MinWidth, MinHeight, MaxWidth, MaxHeight */
  123.     CUSTOMSCREEN        /* Type */
  124. };
  125. static ULONG palette[]=
  126. {
  127.     4<<16,              /* (count<<16)+first */
  128.     0x00000000,0x40404040,0x00000000,
  129.     0x60606060,0xb0b0b0b0,0x60606060,
  130.     0x30303030,0x70707070,0x30303030,
  131.     0x50505050,0x90909090,0x50505050,
  132.     0                   /* end marker */
  133. };
  134.  
  135. static UBYTE pcmbuf[2048], txtbuf[128], *inputmodule=NULL;
  136. static ULONG modeid=0x8004, rtgmode=0, inputclip=0;
  137. static LONG countvblank= -1, countmod, fps, spf, too_slow=0, inputgain=0;
  138. static WORD ende=0, addint=0, pause=0, softint_busy=0, inputconnected=0, inputreconnect=0;
  139. static WORD peak_l=0, peakhold_l=0, peak_r=0, peakhold_r=0;
  140. static WORD redraw_count=0, redraw=2, plot_type=0;
  141. static LONG plot_leftbound, plot_rightbound;
  142. static WORD newstatus=0, newmain=0;
  143.  
  144.  
  145.  
  146.  
  147.  
  148.  
  149.  
  150.  
  151. int __saveds vblank_count(void)
  152. {
  153.     if(countvblank<0)   /** start simultaneously **/
  154.     {
  155.         countvblank=0;
  156.         Delf_Poke(prg_scope->ydata+DATY_SCOPE_MODCOUNT,DMEMF_YDATA,0);
  157.     }
  158.     else                /** count **/
  159.     {
  160.         countvblank++;
  161.         countmod=Delf_Peek(prg_scope->ydata+DATY_SCOPE_MODCOUNT,DMEMF_YDATA);
  162.     }
  163.     return(0);
  164. }
  165.  
  166. int __saveds vblank_plot(void)
  167. {
  168.     if(!pause && !inputreconnect)
  169.     {
  170.         if(--redraw_count<=0)
  171.         {
  172.             redraw_count=redraw;
  173.             if(!softint_busy)
  174.             {
  175.                 softint_busy=1;
  176.                 Cause(&vblank_softint);
  177.             }
  178.             else {too_slow++; redraw_count=1;}
  179.         }
  180.     }
  181.     return(0);
  182. }
  183.  
  184.  
  185.  
  186.  
  187. WORD __saveds plot_bar(UBYTE *p, ULONG avg, WORD peak)
  188. {
  189.     UBYTE *q=p-((peak>0)?peak*640/8:0);
  190.     double l;
  191.     WORD i,v=0;
  192.     if(avg)
  193.     {
  194.         l=log((double)avg/(double)spf/(double)(0x2000))*0.1447648;  /* 60dB */
  195.         v=(UWORD)((l+1.0)*255.0+0.5);
  196.         v=(v>255)?255:((v<0)?0:v);
  197.     }
  198.     for(i=v; i>0; i--)      { (*p)=0xff; p-=640/8; }
  199.     for(i=255-v; i>=0; i--) { (*p)=0x00; p-=640/8; }
  200.     (*q)=0xff;
  201.     return(v);
  202. }
  203.  
  204. int __saveds softint_plot(void)
  205. {
  206.     WORD v;
  207.  
  208.     ASM_prepare_plot();
  209.  
  210.     /*while(Delf_Peek(prg_scope->xdata+DATX_SCOPE_BUSY,DMEMF_XDATA));*/
  211.  
  212.     v=plot_bar(chipmem+2+640/8*448,Delf_Peek(prg_scope->xdata+DATX_SCOPE_AVGL,DMEMF_XDATA),peak_l);
  213.     if(v>peak_l) {peak_l=v; peakhold_l=50;}
  214.     else if(peakhold_l>0) peakhold_l-=redraw; else peak_l-=redraw;
  215.     v=plot_bar(chipmem+4+640/8*448,Delf_Peek(prg_scope->xdata+DATX_SCOPE_AVGR,DMEMF_XDATA),peak_r);
  216.     if(v>peak_r) {peak_r=v; peakhold_r=50;}
  217.     else if(peakhold_r>0) peakhold_r-=redraw; else peak_r-=redraw;
  218.  
  219.     if(plot_type==1)    /* oscilloscope */
  220.     {
  221.         Delf_CopyD2A(prg_scope->ldata+DATL_SCOPE_PCMBUF,pcmbuf,spf>>1,DCPF_XDATA|DCPF_24BIT);
  222.         Delf_CopyD2A(prg_scope->ldata+DATL_SCOPE_PCMBUF,pcmbuf+1024,spf>>1,DCPF_YDATA|DCPF_24BIT);
  223.         Delf_Run(prg_scope->prog+PROG_SCOPE_CONVERT, 0, DRUNF_ASYNCH,
  224.                  spf, (ULONG)plot_type, 0, 0);
  225.         ASM_pcm_plot(pcmbuf,chipmem+640/8*48+(plot_leftbound>>3),spf>>1);
  226.     }
  227.     if(plot_type==2)    /* spectrum analyzer */
  228.     {
  229.         Delf_CopyD2A(prg_scope->ldata+DATL_SCOPE_PCMBUF,pcmbuf,416*2,DCPF_XDATA|DCPF_16BITH);
  230.         Delf_Run(prg_scope->prog+PROG_SCOPE_CONVERT, 0, DRUNF_ASYNCH,
  231.                  spf, (ULONG)plot_type, 0, 0);
  232.         ASM_fft_plot((UWORD*)pcmbuf,chipmem+640/8*113+192/8,(rtgmode)?rp:NULL);
  233.     }
  234.  
  235.     softint_busy=0;
  236.     return(0);
  237. }
  238.  
  239.  
  240.  
  241.  
  242.  
  243.  
  244. int __saveds check_idcmp(void)
  245. {
  246.     struct IntuiMessage *msg;
  247.     while((msg=(struct IntuiMessage*)GetMsg(mywindow->UserPort)))
  248.     {
  249.         switch(msg->Class)
  250.         {
  251.         case IDCMP_VANILLAKEY:
  252.             newstatus++;
  253.             switch(msg->Code)
  254.             {
  255.             case 27:    /*ESC*/
  256.                 ende++;
  257.                 break;
  258.             case 32:    /*Space*/
  259.                 pause=pause?0:1;
  260.                 break;
  261.             case '1':   /*Numbers*/
  262.             case '2':
  263.             case '3':
  264.             case '4':
  265.             case '5':
  266.             case '6':
  267.             case '7':
  268.             case '8':
  269.             case '9':
  270.                 redraw=msg->Code-'0';
  271.                 break;
  272.             case '+':
  273.                 if(inputgain<=210)
  274.                     Delf_SetAttrs(DA_InputGain,((inputgain/15+1)<<12)|0xfff,TAG_END,0);
  275.                 break;
  276.             case '-':
  277.                 if(inputgain>=15)
  278.                     Delf_SetAttrs(DA_InputGain,((inputgain/15-1)<<12)|0xfff,TAG_END,0);
  279.                 break;
  280.             case 'o':
  281.             case 'O':
  282.                 plot_type=1; newmain++;
  283.                 break;
  284.             case 's':
  285.             case 'S':
  286.                 plot_type=2; newmain++;
  287.                 break;
  288.             default:
  289.                 break;
  290.             }
  291.             break;
  292.         case IDCMP_INACTIVEWINDOW:
  293.             pause++;
  294.             break;
  295.         case IDCMP_ACTIVEWINDOW:
  296.             if(pause>0) pause--;
  297.             break;
  298.         }
  299.         ReplyMsg((struct Message*)msg);
  300.     }
  301.     return(0);
  302. }
  303.  
  304.  
  305.  
  306.  
  307. void printstatus(void)
  308. {
  309.     WORD fake_pause=0;
  310.     if(pause==0) {pause=99; fake_pause++;}
  311.     SetDrMd(rp,JAM2);
  312.     SetAPen(rp,1);
  313.     SetBPen(rp,0);
  314.  
  315.     Move(rp,8,40+4+8);
  316.     sprintf(txtbuf,"fps=%d",fps);
  317.     Text(rp,txtbuf,(ULONG)strlen(txtbuf));
  318.     Move(rp,8,40+4+8+8);
  319.     sprintf(txtbuf,"redraw=%d",redraw);
  320.     Text(rp,txtbuf,(ULONG)strlen(txtbuf));
  321.     Move(rp,8,40+4+8+8+8+8);
  322.     sprintf(txtbuf,"pause=o%s",(!fake_pause)?"n ":"ff");
  323.     Text(rp,txtbuf,(ULONG)strlen(txtbuf));
  324.  
  325.     if(inputreconnect)
  326.     {
  327.         struct DelfModule *dm;
  328.         inputconnected=0;
  329.         ObtainSemaphore(mod_scope->semaphore);  /*Disable();*/
  330.         dm=Delf_FindModule(inputmodule);
  331.         if(Delf_SetPipe(dm,0,mod_scope,0) && dm) inputconnected=1;
  332.         ReleaseSemaphore(mod_scope->semaphore); /*Enable();*/
  333.         inputreconnect=0;
  334.     }
  335.  
  336.     if(!inputmodule || strcmp("Connectors",inputmodule)==0)
  337.     {
  338.         sprintf(txtbuf,"gain=%d.%ddB ",inputgain/10,inputgain%10);
  339.         Move(rp,8,104+4+8);
  340.         Text(rp,"rate=48000Hz",12);
  341.         Move(rp,8,104+4+8+8);
  342.         Text(rp,txtbuf,(ULONG)strlen(txtbuf));
  343.         Move(rp,8,104+4+8+8+8+8);
  344.         if(inputclip) {SetDrMd(rp,JAM2|INVERSVID); Text(rp,"  CLIPPING  ",12);}
  345.         else {SetAPen(rp,2); Text(rp,"no clipping ",12);}
  346.     }
  347.     else
  348.     {
  349.         Move(rp,8,104+4+8+8);
  350.         Text(rp,inputmodule,(ULONG)strlen(inputmodule));
  351.         Move(rp,8,104+4+8+8+8);
  352.         if(!inputconnected) {Text(rp,"<not available>",15);}
  353.         else {SetAPen(rp,2); Text(rp,"<connected>    ",15);}
  354.     }
  355.  
  356.     newstatus=0;
  357.     if(fake_pause) pause=0;
  358. }
  359.  
  360. void printmain(void)
  361. {
  362.     UBYTE *p;
  363.     WORD i;
  364.  
  365.     pause+=99;
  366.     SetDrMd(rp,JAM2);
  367.     SetAPen(rp,1);
  368.     SetBPen(rp,0);
  369.  
  370.     Move(rp,0,0);
  371.     ClearScreen(rp);
  372.  
  373.     Move(rp,8,16);
  374.     Text(rp,"Delfina Scope",13);
  375.     Move(rp,8,40);
  376.     Text(rp,"display:",8);
  377.     Move(rp,8,104);
  378.     Text(rp,"audio in:",9);
  379.     Move(rp,8,480-8);
  380.     Text(rp,"An INFECT Millennium Production",31);
  381.     Move(rp,640-20*8,480-8);
  382.     Text(rp,"programmed by Smack",19);
  383.  
  384.     SetAPen(rp,2);
  385.     Move(rp,8,40+4+8+8+8);
  386.     Text(rp,"[1]...[9]",9);
  387.     Move(rp,8,40+4+8+8+8+8+8);
  388.     Text(rp,"[space]",7);
  389.     Move(rp,8,104+4+8+8+8);
  390.     Text(rp,"[+] [-]",7);
  391.  
  392.     p=chipmem+2+640/8*448+640/8*480;
  393.     for(i=255; i>0; i-=2) { (*p)=0xff; p-=640/8*2; }
  394.     p=chipmem+4+640/8*448+640/8*480;
  395.     for(i=255; i>0; i-=2) { (*p)=0xff; p-=640/8*2; }
  396.     Move(rp,44,448-256+4);
  397.     Text(rp," dB",3);
  398.     Move(rp,44,448-256+4+43);
  399.     Text(rp,"-10",3);
  400.     Move(rp,44,448-256+4+85);
  401.     Text(rp,"-20",3);
  402.     Move(rp,44,448-256+4+128);
  403.     Text(rp,"-30",3);
  404.     Move(rp,44,448-256+4+171);
  405.     Text(rp,"-40",3);
  406.     Move(rp,44,448-256+4+213);
  407.     Text(rp,"-50",3);
  408.     Move(rp,44,448-256+4+256);
  409.     Text(rp,"-60",3);
  410.  
  411.     if(plot_type==1)    /* oscilloscope */
  412.     {
  413.         SetAPen(rp,1);
  414.         Move(rp,128+(512-14*8)/2,16);
  415.         Text(rp,"[o]scilloscope",14);
  416.         SetAPen(rp,2);
  417.         Move(rp,128+(512-19*8)/2,16+8);
  418.         Text(rp,"[s]pectrum analyzer",19);
  419.         Move(rp,128+(512-12*8)/2,48+96-3);
  420.         Text(rp,"left channel",12);
  421.         Move(rp,plot_leftbound,48);
  422.         Draw(rp,plot_rightbound,48);
  423.         Move(rp,plot_leftbound,48+96);
  424.         Draw(rp,plot_rightbound,48+96);
  425.         Move(rp,128+(512-13*8)/2,48+96-3+192);
  426.         Text(rp,"right channel",13);
  427.         Move(rp,plot_leftbound,48+192);
  428.         Draw(rp,plot_rightbound,48+192);
  429.         Move(rp,plot_leftbound,48+96+192);
  430.         Draw(rp,plot_rightbound,48+96+192);
  431.         Move(rp,plot_leftbound,48+96+192+96);
  432.         Draw(rp,plot_rightbound,48+96+192+96);
  433.     }
  434.     if(plot_type==2)    /* spectrum analyzer */
  435.     {
  436.         LONG x;
  437.         Move(rp,128+(512-14*8)/2,16);
  438.         Text(rp,"[o]scilloscope",14);
  439.         SetAPen(rp,1);
  440.         Move(rp,128+(512-19*8)/2,16+8);
  441.         Text(rp,"[s]pectrum analyzer",19);
  442.         SetAPen(rp,2);
  443.         Move(rp,192,112); Draw(rp,192+416,112);
  444.         Move(rp,192-4-3*8,112+3); Text(rp,"-20",3);
  445.         Move(rp,192-8-2*8,112+3+21); Text(rp,"dB",2);
  446.         Move(rp,192,112+43); Draw(rp,192+416,112+43);
  447.         Move(rp,192-4-3*8,112+43+3); Text(rp,"-30",3);
  448.         Move(rp,192,112+85); Draw(rp,192+416,112+85);
  449.         Move(rp,192-4-3*8,112+85+3); Text(rp,"-40",3);
  450.         Move(rp,192,112+128); Draw(rp,192+416,112+128);
  451.         Move(rp,192-4-3*8,112+128+3); Text(rp,"-50",3);
  452.         Move(rp,192,112+171); Draw(rp,192+416,112+171);
  453.         Move(rp,192-4-3*8,112+171+3); Text(rp,"-60",3);
  454.         Move(rp,192,112+213); Draw(rp,192+416,112+213);
  455.         Move(rp,192-4-3*8,112+213+3); Text(rp,"-70",3);
  456.         Move(rp,192,112+256); Draw(rp,192+416,112+256);
  457.         Move(rp,192-4-3*8,112+256+3); Text(rp,"-80",3);
  458.  
  459.         Move(rp,192-16,384); Text(rp,"kHz",3);
  460.         for(i=500;i<19500;i+=500)
  461.         {
  462.             rp->LinePtrn=0x5555;
  463.             x=192+(LONG)((double)i*1024.0/48000.0+0.5);
  464.             Move(rp,x,372); Draw(rp,x,108); i+=500;
  465.             rp->LinePtrn=0xffff;
  466.             x=192+(LONG)((double)i*1024.0/48000.0+0.5);
  467.             Move(rp,x,374); Draw(rp,x,106);
  468.             Move(rp,x-(i>9999?8:4),384);
  469.             sprintf(txtbuf,"%d",i/1000); Text(rp,txtbuf,(ULONG)strlen(txtbuf));
  470.         }
  471.     }
  472.  
  473.     if(pause>=99) pause-=99;
  474.     printstatus();
  475.     newmain=0;
  476. }
  477.  
  478.  
  479.  
  480.  
  481. int main(void)
  482. {
  483.     struct RDArgs *rdargs;
  484.     LONG args[3]={0,0,0};
  485.     struct rtScreenModeRequester *rtscmreq=NULL;
  486.     struct NameInfo nameinfo;
  487.     struct DelfMsg *delfmsg;
  488.     int rc=0;
  489.  
  490.     GFXBASE=FindName(&SysBase->LibList,"graphics.library");
  491.     rdargs=ReadArgs(template,args,NULL);
  492.     printf("\33[1m%s by Smack/Infect!\33[0m\n",&version[6]);
  493.     inputmodule=(UBYTE*)args[1];
  494.     rtgmode=args[2];
  495.     if(args[0])
  496.     {
  497.         int b=10;
  498.         UBYTE *pt=(UBYTE*)args[0];
  499.         if(pt[0]=='$') {pt++; b=16;}
  500.         if((pt[0]=='0')&&((pt[1]=='x')||(pt[1]=='X'))) {pt+=2; b=16;}
  501.         modeid=strtoul(pt,NULL,b);
  502.     }
  503.     else
  504.     {
  505.         if((ReqToolsBase=(struct ReqToolsBase*)OpenLibrary("reqtools.library",38)))
  506.         {
  507.             if((rtscmreq=rtAllocRequest(RT_SCREENMODEREQ,NULL)))
  508.             {
  509.                 if(!rtScreenModeRequest(rtscmreq, "DelfScope: select (640x480) mode",
  510.                                         RTSC_Flags, SCREQF_GUIMODES,
  511.                                         RTSC_MinWidth, 640,
  512.                                         RTSC_MinHeight, 480,
  513.                                         RTSC_MinDepth, 2,
  514.                                         RTSC_MaxDepth, 8,
  515.                                         TAG_DONE ))
  516.                 goto exit_clean;
  517.                 modeid=rtscmreq->DisplayID;
  518.             }
  519.         }
  520.     }
  521.     if(!GetDisplayInfoData(NULL,(UBYTE*)&nameinfo,sizeof(struct NameInfo),DTAG_NAME,modeid)) nameinfo.Name[0]='\0';
  522.     printf("  selected: modeid=0x%x (%s)\n",modeid,nameinfo.Name);
  523.     if(inputmodule) printf("  input module: '%s'\n",inputmodule);
  524. #ifdef RTGMODE
  525.     printf("  RTG mode=o%s\n",(rtgmode)?"n":"ff");
  526. #endif
  527.  
  528.     if(!(DelfinaBase=OpenLibrary("delfina.library",4)))
  529.     {
  530.         printf("**unable to open delfina.library V4\n");
  531.         rc=20;
  532.         goto exit_clean;
  533.     }
  534.     if(!(prg_scope=Delf_AddPrg(&DSP56K_SCOPE)))
  535.     {
  536.         printf("**not enough Delfina memory\n");
  537.         rc=20;
  538.         goto exit_clean;
  539.     }
  540.     if(!(mod_scope=Delf_AddModule(DM_Inputs,1, DM_Outputs,1,
  541.                                   DM_Code,prg_scope->prog+PROG_SCOPE_MODULE,
  542.                                   DM_Freq,48000,
  543.                                   DM_Name,"DelfScope",
  544.                                   0)))
  545.     {
  546.         printf("**couldn't create DelfModule\n");
  547.         rc=20;
  548.         goto exit_clean;
  549.     }
  550.     if(!(delfport=Delf_StartNotify(DA_InputGainL,DA_InputClip,DA_UpdateMod,0)))
  551.     {
  552.         printf("**couldn't create Delf_Notify port\n");
  553.         rc=20;
  554.         goto exit_clean;
  555.     }
  556.     inputgain=15*(Delf_GetAttr(DA_InputGainL,0)>>12);
  557.     inputconnected=1;
  558.     if(inputmodule)
  559.     {
  560.         struct DelfModule *dm;
  561.         dm=Delf_FindModule(inputmodule);
  562.         if(Delf_SetPipe(dm,0,mod_scope,0) && dm) printf("  input connect ok.\n");
  563.         else {printf("**input connect failed.\n"); inputconnected=0;}
  564.     }
  565.  
  566.     if(!(chipmem=AllocMem(640*480/4,MEMF_CHIP|MEMF_CLEAR|MEMF_PUBLIC)))
  567.     {
  568.         printf("**not enough graphics memory\n");
  569.         rc=20;
  570.         goto exit_clean;
  571.     }
  572.     bmap.Planes[0]=chipmem;
  573.     bmap.Planes[1]=chipmem+640*480/8;
  574.     if(!(myscreen=OpenScreenTags(&newscr,
  575.                                  SA_DisplayID,modeid,
  576.                                  SA_Colors32,palette,
  577.                                  SA_Overscan,OSCAN_STANDARD,
  578.                                  SA_BackFill,1, /*LAYERS_NOBACKFILL*/
  579.                                  TAG_END,0)))
  580.     {
  581.         printf("**unable to open screen\n");
  582.         rc=20;
  583.         goto exit_clean;
  584.     }
  585.     rp= &myscreen->RastPort;
  586.     {   /*** check the properties of the screen we just opened ***/
  587.         ULONG modeid2;
  588.         modeid2=GetVPModeID(&myscreen->ViewPort);
  589.         if(!GetDisplayInfoData(NULL,(UBYTE*)&nameinfo,sizeof(struct NameInfo),DTAG_NAME,modeid2)) nameinfo.Name[0]='\0';
  590.         if(modeid!=modeid2) printf("  actual:   modeid=0x%x (%s)  **promoted**\n",modeid2,nameinfo.Name);
  591.         if(rp->BitMap->Planes[0]!=chipmem)
  592.         {
  593.             printf("**it seems that we've got a graphics board screenmode here!\n"
  594.                    "**sorry, but this program works with Amiga native (ECS/AGA) modes only.\n");
  595.             goto exit_clean;
  596.         }
  597.     }
  598.     textfont=OpenFont(&textattr);
  599.     SetFont(rp,textfont);
  600.     newwin.Screen=myscreen;
  601.     if(!(mywindow=OpenWindowTags(&newwin,
  602.                                  WA_BackFill,1, /*LAYERS_NOBACKFILL*/
  603.                                  TAG_END,0)))
  604.     {
  605.         printf("**unable to open window\n");
  606.         rc=20;
  607.         goto exit_clean;
  608.     }
  609.     Disable();
  610.     mywindow->UserPort->mp_Flags=PA_SOFTINT;
  611.     mywindow->UserPort->mp_SigTask=(void*)&window_int;
  612.     Enable();
  613.  
  614.     printmain();
  615.     SetAPen(rp,1);
  616.     Move(rp,128+(512-17*8)/2,240);
  617.     Text(rp,"< synchronizing >",17);
  618.     {
  619.         double d_fps, d_spf;
  620.         vblank_int.is_Code=(void(*)(void))vblank_count;
  621.         AddIntServer(INTB_VERTB,&vblank_int);
  622.         while(countvblank<200);
  623.         RemIntServer(INTB_VERTB,&vblank_int);
  624.         d_fps=(double)countvblank/((double)countmod*128.0/48000.0);
  625.         d_spf=(double)countmod*128.0/(double)countvblank;
  626.         fps=(LONG)(d_fps+0.5);
  627.         spf=(LONG)(d_spf+0.5);
  628.         if(spf>1024) spf=1024;
  629.         printf("  vbl=%d mod=%d   fps=%f (%d)  spf=%f (%d)\n",
  630.                 countvblank,countmod,d_fps,fps,d_spf,spf );
  631.         fflush(stdout);
  632.         plot_leftbound=128+((((1024/2-(spf>>1)-31)>>5))<<5);
  633.         plot_rightbound=plot_leftbound+((spf>>4)<<3)-1;
  634.     }
  635.     plot_type=1;
  636.     printmain();
  637.     newstatus++;
  638.  
  639.     vblank_int.is_Code=(void(*)(void))vblank_plot;
  640.     AddIntServer(INTB_VERTB,&vblank_int);
  641.     addint++;
  642.  
  643.     while(!ende)
  644.     {
  645.         Delay(1);
  646.         while((delfmsg=(struct DelfMsg*)GetMsg(delfport)))
  647.         {
  648.             struct TagItem *ti;
  649.             if((ti=FindTagItem(DA_InputGainL,delfmsg->taglist)))
  650.                 inputgain=15*(ti->ti_Data>>12);
  651.             if((ti=FindTagItem(DA_InputClip,delfmsg->taglist)))
  652.                 inputclip=ti->ti_Data;
  653.             if((ti=FindTagItem(DA_UpdateMod,delfmsg->taglist)))
  654.             {
  655.                 /*printf(":::updateMod::: '%s'\n",ti->ti_Data);*/
  656.                 if(strcmp("DelfScope",(UBYTE*)ti->ti_Data)==0) inputreconnect++;
  657.                 else if(inputmodule && strcmp(inputmodule,(UBYTE*)ti->ti_Data)==0) inputreconnect++;
  658.             }
  659.             delfmsg->result=0;
  660.             ReplyMsg(&delfmsg->msg);
  661.             newstatus++;
  662.         }
  663.         if(newmain) printmain();
  664.         if(newstatus) printstatus();
  665.     }
  666.  
  667.     if(too_slow>0) printf("  detected REDRAW_BUSY %d times\n",too_slow);
  668.  
  669. exit_clean:
  670.     if(addint) RemIntServer(INTB_VERTB,&vblank_int);
  671.     if(delfport) Delf_EndNotify(delfport);
  672.     if(mod_scope) Delf_RemModule(mod_scope);
  673.     if(prg_scope) Delf_RemPrg(prg_scope);
  674.     if(DelfinaBase) CloseLibrary(DelfinaBase);
  675.     if(mywindow) CloseWindow(mywindow);
  676.     if(myscreen) CloseScreen(myscreen);
  677.     if(chipmem) FreeMem(chipmem,640*480/4);
  678.     if(textfont) CloseFont(textfont);
  679.     if(rdargs) FreeArgs(rdargs);
  680.     if(rtscmreq) rtFreeRequest(rtscmreq);
  681.     if(ReqToolsBase) CloseLibrary((struct Library*)ReqToolsBase);
  682.     return(rc);
  683. }
  684.  
  685.